package com.zmn.oms.admin.controller.common;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.zmn.act.common.model.subject.coupon.SubjectCouponDIO;
import com.zmn.act.common.model.subject.coupon.VasProductCouponDRO;
import com.zmn.act.dubbo.interfaces.subject.list.SubjectListRemoteService;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.collection.CollectionUtil;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.common.utils.math.MathUtil;
import com.zmn.common.utils.math.MoneyUtil;
import com.zmn.common.utils.string.StringUtil;
import com.zmn.consts.GlobalConsts;
import com.zmn.dms.common.dro.coup.scenario.CoupScenarioBatchDRO;
import com.zmn.dms.common.dto.activity.dro.ActivityExplainDRO;
import com.zmn.dms.common.dto.coup.dio.coupon.CoupGetAvailableParamDIO;
import com.zmn.dms.common.dto.coup.dro.activity.ActCouponProductDRO;
import com.zmn.dms.common.dto.coup.dro.coupon.CoupOnAllAvailableDRO;
import com.zmn.dms.common.dto.coup.dro.coupon.CoupOnAvailableDRO;
import com.zmn.dms.common.dto.coup.query.ActCoupQuery;
import com.zmn.dms.common.dto.promotion.dio.PromotionListDIO;
import com.zmn.dms.common.dto.promotion.dro.PromotionDRO;
import com.zmn.dms.common.enums.DiscountTypeEnums;
import com.zmn.dms.dubbo.interfaces.activity.ActivityInfoListRemoteService;
import com.zmn.dms.dubbo.interfaces.coup.coupon.CoupGetRemoteService;
import com.zmn.dms.dubbo.interfaces.prom.PromListRemoteService;
import com.zmn.oms.admin.controller.OmsBaseController;
import com.zmn.oms.common.dto.ResultDTO;
import com.zmn.oms.model.dto.discount.ShowDiscountDTO;
import com.zmn.oms.model.vo.discount.*;
import com.zmn.uuc.common.dro.user.UserBaseDRO;
import com.zmn.uuc.common.query.user.UserMobilePlatQuery;
import com.zmn.uuc.dubbo.interfaces.user.UserListRemoteService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 类描述：优惠
 *
 * @author liuying
 * @date 2021/12/07 11:18
 */
@Slf4j
@Controller
@RequestMapping("/common")
public class DiscountController extends OmsBaseController {

    @Reference(version = com.zmn.dms.dubbo.utils.DubboConsts.INTERFACE_VERSION, check = false)
    private PromListRemoteService promListRemoteService;
    @Reference(version = com.zmn.dms.dubbo.utils.DubboConsts.INTERFACE_VERSION, check = false)
    private CoupGetRemoteService coupGetRemoteService;
    @Reference(version = com.zmn.dms.dubbo.utils.DubboConsts.INTERFACE_VERSION, check = false)
    private ActivityInfoListRemoteService activityInfoListRemoteService;
    @Reference(version = com.zmn.act.common.consts.ActConsts.INTERFACE_VERSION, check = false)
    private SubjectListRemoteService subjectListRemoteService;
    @Reference(version = com.zmn.uuc.common.constant.DubboConsts.INTERFACE_VERSION, check = false)
    private UserListRemoteService uucUserListRemoteService;

    /**
     * 查找优惠信息
     *
     * @param showDiscountDTO
     * @return
     */
    @GetMapping("/check/discount")
    @ResponseBody
    public ResultDTO discount(ShowDiscountDTO showDiscountDTO) {
        ShowDiscountVO discountVO = new ShowDiscountVO();

        // 查询优惠
        discountVO.setUserDiscountList(this.listDiscountByQuery(showDiscountDTO));
        // 促销优惠
        discountVO.setPromotionDiscountList(this.listPromotion(showDiscountDTO));
        // 第三方活动优惠
        discountVO.setThirdDiscountList(this.listThirdDiscount(showDiscountDTO));
        // 关联增值产品优惠券
        discountVO.setIncrementDiscountList(this.listIncrementDiscount(showDiscountDTO));
        // 用户绑定优惠
        discountVO.setUserBindDiscountList(this.listUserBindDiscount(showDiscountDTO));

        // 既没有促销优惠也没有用户优惠，返回失败
        if (CollectionUtil.isNullOrEmpty(discountVO.getPromotionDiscountList())
                && CollectionUtil.isNullOrEmpty(discountVO.getUserDiscountList())
                && CollectionUtil.isNullOrEmpty(discountVO.getThirdDiscountList())
                && CollectionUtil.isNullOrEmpty(discountVO.getIncrementDiscountList())
                && CollectionUtil.isNullOrEmpty(discountVO.getUserBindDiscountList())) {
            return ResultDTO.fail("没有优惠");
        }

        return ResultDTO.success(discountVO);
    }

    /**
     * 获取优惠
     *
     * @param showDiscountDTO
     * @return
     */
    private List<UserDiscountVO> listDiscountByQuery(ShowDiscountDTO showDiscountDTO) {
        List<UserDiscountVO> allDiscount = Lists.newArrayList();
        try {
            ActCoupQuery actCoupQuery = new ActCoupQuery();
            actCoupQuery.setChannelId(showDiscountDTO.getChannelId());
            actCoupQuery.setCityId(showDiscountDTO.getCityId());
            actCoupQuery.setProductIds(Lists.newArrayList(showDiscountDTO.getProductId()));
            logger.debug("查询优惠入参：[{}]", JSON.toJSONString(actCoupQuery));
            ResponseDTO<List<ActCouponProductDRO>> listResponseDTO = activityInfoListRemoteService.listProductDetailActByQuery(actCoupQuery);
            logger.debug("查询优惠出参：[{}]", JSON.toJSONString(listResponseDTO));
            if (listResponseDTO.isSuccess() && CollectionUtil.isNotNullOrEmpty(listResponseDTO.getData())) {
                // 过滤预热活动
                List<ActCouponProductDRO> droList = listResponseDTO.getData();
                List<UserDiscountVO> discountList = Lists.newArrayListWithCapacity(droList.size());
                droList.forEach(dro -> {
                    UserDiscountVO vo = new UserDiscountVO();
                    int type = dro.getPreferentialType();
                    String info;
                    if (Objects.equals(type, GlobalConsts.NO)) {
                        info = MathUtil.div(dro.getPreferentialValue(), 10) + "折";
                    } else {
                        info = MoneyUtil.parseToYuanStr(dro.getPreferentialValue()) + "元";
                    }
                    vo.setDiscountTypeName(DiscountTypeEnums.getSubName(dro.getCoupType()));
                    vo.setQuota(info);
                    vo.setUseCondition("满" + MoneyUtil.parseToYuanStr(dro.getUseCondition()) + "元可用");
                    vo.setPeriodValidity(DateUtil.dateFormatToString(dro.getActLifeTime(), DateUtil.FORMAT_DEFAULT)
                            + "--" + DateUtil.dateFormatToString(dro.getActExpireTime(), DateUtil.FORMAT_DEFAULT));
                    vo.setDesc(dro.getActDesc());
                    discountList.add(vo);
                });
                allDiscount.addAll(discountList);
            }
        } catch (Exception e) {
            log.error("查看用户优惠异常：[{}]", e.getMessage());
        }

        try {
            SubjectCouponDIO dio = new SubjectCouponDIO();
            dio.setChannelId(showDiscountDTO.getChannelId());
            dio.setCityId(showDiscountDTO.getCityId());
            dio.setProductIds(Lists.newArrayList(showDiscountDTO.getProductId()));
            logger.info("查询专题活动入参：[{}]", JSON.toJSONString(dio));
            ResponseDTO<List<CoupScenarioBatchDRO>> firstPage = subjectListRemoteService.listCouponFromFirstPage(dio);
            logger.info("查询专题活动出参：[{}]", JSON.toJSONString(firstPage));
            if (firstPage.isSuccess() && CollectionUtil.isNotNullOrEmpty(firstPage.getData())) {
                List<CoupScenarioBatchDRO> droList = firstPage.getData();
                List<UserDiscountVO> subjectDiscount = Lists.newArrayListWithCapacity(droList.size());
                droList.forEach(dro -> {
                    UserDiscountVO vo = new UserDiscountVO();
                    int type = dro.getPreferentialType();
                    String info;
                    if (Objects.equals(type, GlobalConsts.NO)) {
                        info = MathUtil.div(dro.getPreferentialValue(), 10) + "折";
                    } else {
                        info = MoneyUtil.parseToYuanStr(dro.getPreferentialValue()) + "元";
                    }
                    vo.setDiscountTypeName(DiscountTypeEnums.getSubName(dro.getCoupType()));
                    vo.setQuota(info);
                    vo.setUseCondition("满" + MoneyUtil.parseToYuanStr(dro.getUseCondition()) + "元可用");
                    vo.setPeriodValidity(DateUtil.dateFormatToString(dro.getLifeTime(), DateUtil.FORMAT_DEFAULT)
                            + "--" + DateUtil.dateFormatToString(dro.getExpireTime(), DateUtil.FORMAT_DEFAULT));
                    vo.setDesc(dro.getDesc());
                    subjectDiscount.add(vo);
                });
                allDiscount.addAll(subjectDiscount);
            }
        } catch (Exception e) {
            log.error("查看专题活动异常：[{}]", e.getMessage());
        }

        return allDiscount;
    }

    /**
     * 获取促销优惠
     *
     * @param showDiscountDTO
     * @return
     */
    private List<PromotionDiscountVO> listPromotion(ShowDiscountDTO showDiscountDTO) {

        PromotionListDIO promotionListDIO = new PromotionListDIO();
        promotionListDIO.setPlat(showDiscountDTO.getPlat());
        promotionListDIO.setChannelId(showDiscountDTO.getChannelId());
        promotionListDIO.setCityId(showDiscountDTO.getCityId());
        promotionListDIO.setProductIds(Lists.newArrayList(showDiscountDTO.getProductId()));
        promotionListDIO.setTariffOnoff(showDiscountDTO.getServItemType() == GlobalConsts.YES ? GlobalConsts.YES : GlobalConsts.NO);
        promotionListDIO.setUntariffOnoff(showDiscountDTO.getServItemType() == GlobalConsts.YES ? GlobalConsts.NO : GlobalConsts.YES);
        promotionListDIO.setInWarranty(showDiscountDTO.getBizType() == com.zmn.consts.GlobalConsts.BIZ_TYPE_F ? GlobalConsts.YES : GlobalConsts.NO);
        promotionListDIO.setOutWarranty(showDiscountDTO.getBizType() == com.zmn.consts.GlobalConsts.BIZ_TYPE_C ? GlobalConsts.YES : GlobalConsts.NO);
        promotionListDIO.setEngineerBusiness(showDiscountDTO.getBizType() == com.zmn.consts.GlobalConsts.BIZ_TYPE_B ? GlobalConsts.YES : GlobalConsts.NO);
        promotionListDIO.setExtendedWarranty(GlobalConsts.NO);
        promotionListDIO.setUnextendedWarranty(GlobalConsts.YES);
        logger.debug("查询促销优惠入参：[{}]", JSON.toJSONString(promotionListDIO));
        ResponseDTO<List<PromotionDRO>> responseDTO = promListRemoteService.listNormalProms(promotionListDIO);
        logger.debug("查询促销优惠出参：[{}]", JSON.toJSONString(responseDTO));
        if (!responseDTO.isSuccess() || CollectionUtil.isNullOrEmpty(responseDTO.getData())) {
            return Lists.newArrayList();
        }

        List<PromotionDRO> promotionDROS = responseDTO.getData();
        List<PromotionDiscountVO> promotionDiscountList = Lists.newArrayListWithCapacity(promotionDROS.size());
        promotionDROS.forEach(dro -> {
            PromotionDiscountVO promotionDiscountVO = new PromotionDiscountVO();
            int mode = dro.getMode();
            promotionDiscountVO.setDiscountTypeName(mode == GlobalConsts.NO ? "折扣" : "满减");
            String info;
            if (Objects.equals(mode, GlobalConsts.YES)) {
                info = "满" + MoneyUtil.parseToYuanStr(dro.getOrderAmount().intValue()) + "元减" + MoneyUtil.parseToYuanStr(dro.getReduce().intValue());
            } else {
                info = "满" + MoneyUtil.parseToYuanStr(dro.getOrderAmount().intValue()) + "元" + MathUtil.div(dro.getDiscount().intValue(), 10) + "折";
            }
            promotionDiscountVO.setDiscountInfo(info);
            promotionDiscountVO.setDiscountTime("(" + DateUtil.dateFormatToString(dro.getBeginTime(), DateUtil.FORMAT_DEFAULT)
                    + "--" + DateUtil.dateFormatToString(dro.getEndTime(), DateUtil.FORMAT_DEFAULT) + ")");
            promotionDiscountVO.setDesc(dro.getDesc());
            promotionDiscountList.add(promotionDiscountVO);
        });
        return promotionDiscountList;

    }

    /**
     * 获取第三方活动优惠
     *
     * @param showDiscountDTO
     * @return
     */
    private List<ThirdDiscountVO> listThirdDiscount(ShowDiscountDTO showDiscountDTO) {

        try {
            logger.info("查询第三方活动优惠入参：渠道【{}】-城市【{}】", showDiscountDTO.getChannelId(), showDiscountDTO.getCityId());
            ResponseDTO<List<ActivityExplainDRO>> responseDTO = activityInfoListRemoteService.getActivityExplainList(showDiscountDTO.getChannelId(), showDiscountDTO.getCityId());
            logger.info("查询第三方活动优惠出参：【{}】", JSON.toJSONString(responseDTO));
            if (!responseDTO.isSuccess() || CollectionUtil.isNullOrEmpty(responseDTO.getData())) {
                return null;
            }

            List<ActivityExplainDRO> droList = responseDTO.getData();
            List<ThirdDiscountVO> thirdList = Lists.newArrayListWithCapacity(droList.size());
            droList.forEach(dro -> {
                ThirdDiscountVO vo = new ThirdDiscountVO();
                vo.setDesc(dro.getActivityExplain());
                thirdList.add(vo);
            });
            return thirdList;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("查询第三方活动优惠失败：【{}】", e.getMessage());
            return null;
        }
    }

    /**
     * 获取增值产品优惠
     *
     * @param showDiscountDTO
     * @return
     */
    private List<IncrementDiscountVO> listIncrementDiscount(ShowDiscountDTO showDiscountDTO) {

        try {
            logger.info("查询增值产品优惠入参：渠道【{}】-城市【{}】", showDiscountDTO.getChannelId(), showDiscountDTO.getCityId());
            ResponseDTO<List<VasProductCouponDRO>> responseDTO = subjectListRemoteService.listVasProductCoupon(showDiscountDTO.getChannelId(), showDiscountDTO.getCityId());
            logger.info("查询增值产品优惠出参：【{}】", JSON.toJSONString(responseDTO));
            if (!responseDTO.isSuccess() || CollectionUtil.isNullOrEmpty(responseDTO.getData())) {
                return null;
            }

            List<VasProductCouponDRO> droList = responseDTO.getData();
            List<IncrementDiscountVO> incrementList = Lists.newArrayListWithCapacity(droList.size());
            droList.forEach(dro -> {
                IncrementDiscountVO vo = new IncrementDiscountVO();
                vo.setIncrementProductName(dro.getName());
                vo.setIncrementProductPrice(MoneyUtil.parseToYuanStr(dro.getPrice()));
                vo.setOriginalPrice(MoneyUtil.parseToYuanStr(dro.getOriginalPrice()));
                vo.setDiscountType(dro.getPreferentialType() == GlobalConsts.NO ? "折扣" : "满减");
                vo.setQuota(dro.getPreferentialType() == GlobalConsts.NO ? MathUtil.div(dro.getPreferentialValue(), 10) + "折" : MoneyUtil.parseToYuanStr(dro.getPreferentialValue()) + "元");
                vo.setUseCondition("满" + MoneyUtil.parseToYuanStr(dro.getUseCondition()) + "元可用");
                vo.setPeriodValidity(DateUtil.dateFormatToString(dro.getLifeTime(), DateUtil.FORMAT_DEFAULT)
                        + "--" + DateUtil.dateFormatToString(dro.getExpireTime(), DateUtil.FORMAT_DEFAULT));
                vo.setDesc(dro.getDesc());
                incrementList.add(vo);
            });
            return incrementList;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("查询增值产品优惠失败：【{}】", e.getMessage());
            return null;
        }
    }

    /**
     * 获取用户绑定优惠
     *
     * @param showDiscountDTO
     * @return
     */
    private List<UserDiscountVO> listUserBindDiscount(ShowDiscountDTO showDiscountDTO) {

        try {
            // 呼叫下单查询用户优惠
            if (StringUtil.isNotBlank(showDiscountDTO.getCallId())
                    && StringUtil.isNotBlank(showDiscountDTO.getTelephone())) {

                UserMobilePlatQuery query = new UserMobilePlatQuery();
                query.setMobile(showDiscountDTO.getTelephone());
                query.setPlat(showDiscountDTO.getPlat());
                logger.debug("查询userId入参：[{}]", JSON.toJSONString(query));
                ResponseDTO<List<UserBaseDRO>> responseDTO = uucUserListRemoteService.listUserByMobileAndPlat(query);
                logger.debug("查询userId出参：[{}]", JSON.toJSONString(responseDTO));
                if (!responseDTO.isSuccess() || CollectionUtil.isNullOrEmpty(responseDTO.getData())) {
                    return null;
                }

                List<Long> userIdList = responseDTO.getData().stream().map(UserBaseDRO::getUserId).collect(Collectors.toList());

                CoupGetAvailableParamDIO coupGetAvailableParamDIO = new CoupGetAvailableParamDIO();
                coupGetAvailableParamDIO.setUserIds(userIdList);
                coupGetAvailableParamDIO.setChannelId(showDiscountDTO.getChannelId());
                coupGetAvailableParamDIO.setCityId(showDiscountDTO.getCityId());
                coupGetAvailableParamDIO.setProductId(showDiscountDTO.getProductId());
                coupGetAvailableParamDIO.setTariffOnoff(showDiscountDTO.getServItemType() == GlobalConsts.YES ? GlobalConsts.YES : GlobalConsts.NO);
                coupGetAvailableParamDIO.setUntariffOnoff(showDiscountDTO.getServItemType() == GlobalConsts.YES ? GlobalConsts.NO : GlobalConsts.YES);
                coupGetAvailableParamDIO.setInWarranty(showDiscountDTO.getBizType() == com.zmn.consts.GlobalConsts.BIZ_TYPE_F ? GlobalConsts.YES : GlobalConsts.NO);
                coupGetAvailableParamDIO.setOutWarranty(showDiscountDTO.getBizType() == com.zmn.consts.GlobalConsts.BIZ_TYPE_C ? GlobalConsts.YES : GlobalConsts.NO);
                coupGetAvailableParamDIO.setEngineerBusiness(showDiscountDTO.getBizType() == com.zmn.consts.GlobalConsts.BIZ_TYPE_B ? GlobalConsts.YES : GlobalConsts.NO);
                coupGetAvailableParamDIO.setExtendedWarranty(GlobalConsts.NO);
                coupGetAvailableParamDIO.setUnextendedWarranty(GlobalConsts.YES);
                coupGetAvailableParamDIO.setOrderTime(DateUtil.getNow());
                logger.info("查询用户优惠入参：[{}]", JSON.toJSONString(coupGetAvailableParamDIO));
                ResponseDTO<CoupOnAllAvailableDRO> dto = coupGetRemoteService.getAvailableCoup(coupGetAvailableParamDIO);
                logger.info("查询用户优惠出参：[{}]", JSON.toJSONString(dto));

                if (!dto.isSuccess() || Objects.isNull(dto.getData())) {
                    return null;
                }

                List<CoupOnAvailableDRO> coupOnAvailableDROS = dto.getData().getCoupOnAvailableDROS();
                if (CollectionUtil.isNullOrEmpty(coupOnAvailableDROS)) {
                    return null;
                }

                List<UserDiscountVO> userDiscountList = Lists.newArrayListWithCapacity(coupOnAvailableDROS.size());
                coupOnAvailableDROS.forEach(dro -> {
                    UserDiscountVO userDiscountVO = new UserDiscountVO();
                    userDiscountVO.setBatchName(dro.getBatchName());
                    userDiscountVO.setReleaseTime(DateUtil.dateFormatToString(dro.getCreateTime(), DateUtil.FORMAT_DEFAULT));
                    int type = dro.getPreferentialType();
                    String info;
                    if (Objects.equals(type, GlobalConsts.NO)) {
                        info = MathUtil.div(dro.getPreferentialValue(), 10) + "折";
                    } else {
                        info = MoneyUtil.parseToYuanStr(dro.getFaceValue()) + "元";
                    }
                    userDiscountVO.setDiscountTypeName(type == GlobalConsts.NO ? "折扣" : "满减");
                    userDiscountVO.setQuota(info);
                    userDiscountVO.setUseCondition("满" + MoneyUtil.parseToYuanStr(dro.getUseCondition()) + "元可用");
                    userDiscountVO.setPeriodValidity(DateUtil.dateFormatToString(dro.getLifeTime(), DateUtil.FORMAT_DEFAULT)
                            + "--" + DateUtil.dateFormatToString(dro.getExpireTime(), DateUtil.FORMAT_DEFAULT));
                    userDiscountList.add(userDiscountVO);
                });
                return userDiscountList;
            }
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("查询用户绑定优惠失败：【{}】", e.getMessage());
            return null;
        }
    }

    /**
     * 优惠信息页面
     *
     * @return
     */
    @RequestMapping("/show/discount")
    public ModelAndView discount() {
        ModelAndView mv = new ModelAndView("order/showDiscount");
        return mv;
    }

    /**
     * 优惠信息页面
     *
     * @return
     */
    @RequestMapping("/select/discount")
    public ModelAndView selectDiscount() {
        ModelAndView mv = new ModelAndView("work/modify/selectDiscount");
        // 省份
        mv.addObject("provinceList", super.getAllProvinceList());
        // 城市ID
        mv.addObject("cityList", super.getAllCityList());
        // 服务分类
        mv.addObject("servCategList", super.getShowServCategList());
        return mv;
    }

}
